// **************************************************************
// COPYRIGHT(c)2020, Xidian University
// All rights reserved.
//
// IP LIB INDEX :  
// IP Name      :      
// File name    : crossbar_ctl_top.v
// Module name  : crossbar_ctl_top
// Full name    :  
//
// Author       : Hbing
// Email        : 2629029232@qq.com
// Data         : 2020/9/12
// Version      : V 1.0 
// 
// Abstract     : 
// Called by    :  
// 
// Modification history
// -----------------------------------------------------------------
// 
// 
// 
// *****************************************************************
// `include "top_define.v"
// *******************
// TIMESCALE
// ******************* 
`timescale 1ns/1ps 

// *******************
// DESCRIPTION
// *******************
// 3*3交叉节点，但是为了防止阻塞，第三列交叉节点中的乒乓RAM翻倍，分别存port2,port3目的端口的数据帧
// 
// 
//*******************
//DEFINE(s)
//*******************
//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

//*******************
//DEFINE MODULE PORT
//*******************
module crossbar_ctl_top(
    //sysrem input/output
    input  wire         clk                 ,
    input  wire         rst_n               ,
    input wire   [9:0]  ram_2p_cfg_register,
    //10G--01
    //with bus_master_tx
    input  wire [255:0] emac_data_in       ,
    input  wire         emac_data_wren     ,
    input  wire [  5:0] rx_address_dpram   ,
    input  wire [  3:0] mac_dest_port_in   ,
    input  wire         mul_indicate       ,
    (*mark_debug = "true"*) output wire         uni_tx_rdy0        ,
    (*mark_debug = "true"*) output wire         uni_tx_rdy1        ,
    (*mark_debug = "true"*) output wire         uni_tx_rdy2        ,
    (*mark_debug = "true"*) output wire         uni_tx_rdy3        ,
    (*mark_debug = "true"*) output wire         mul_tx_rdy0        ,
    (*mark_debug = "true"*) output wire         mul_tx_rdy1        ,
    (*mark_debug = "true"*) output wire         mul_tx_rdy2        ,
    (*mark_debug = "true"*) output wire         mul_tx_rdy3        ,
    //with MAC_IP
    input  wire         emac_rx_ready0      ,
    output wire [255:0] emac_data_final0    ,
    output wire         emac_dval_final0    ,
    output wire         emac_dsav_final0    ,
    output wire         emac_sop_final0     ,
    output wire         emac_eop_final0     ,
    output wire [  4:0] emac_mod_final0     ,
    output wire [  3:0] mac_dest_port_out0  ,
    output wire         uni_out_busy0       ,
    output wire         mul_out_busy0       ,
    input  wire         out_enable0         ,
    output wire [ 10:0] emac_len_final0     ,
    //output wire [  2:0] emac_pri_final0     ,
    output wire         read_finish0        ,

    input  wire         emac_rx_ready1      ,
    output wire [255:0] emac_data_final1    ,
    output wire         emac_dval_final1    ,
    output wire         emac_dsav_final1    ,
    output wire         emac_sop_final1     ,
    output wire         emac_eop_final1     ,
    output wire [  4:0] emac_mod_final1     ,
    output wire [  3:0] mac_dest_port_out1  ,
    output wire         uni_out_busy1       ,
    output wire         mul_out_busy1       ,
    input  wire         out_enable1         ,
    output wire [ 10:0] emac_len_final1     ,
    //output wire [  2:0] emac_pri_final1     ,
    output wire         read_finish1        ,

    input  wire         emac_rx_ready2      ,
    output wire [255:0] emac_data_final2    ,
    output wire         emac_dval_final2    ,
    output wire         emac_dsav_final2    ,
    output wire         emac_sop_final2     ,
    output wire         emac_eop_final2     ,
    output wire [  4:0] emac_mod_final2     ,
    output wire [  3:0] mac_dest_port_out2  ,
    output wire         uni_out_busy2       ,
    output wire         mul_out_busy2       ,
    input  wire         out_enable2         ,
    output wire [ 10:0] emac_len_final2     ,
    //output wire [  2:0] emac_pri_final2     ,
    output wire         read_finish2        ,

    input  wire         emac_rx_ready3      ,
    output wire [255:0] emac_data_final3    ,
    output wire         emac_dval_final3    ,
    output wire         emac_dsav_final3    ,
    output wire         emac_sop_final3     ,
    output wire         emac_eop_final3     ,
    output wire [  4:0] emac_mod_final3     ,
    output wire [  3:0] mac_dest_port_out3  ,
    output wire         uni_out_busy3       ,
    output wire         mul_out_busy3       ,
    input  wire         out_enable3         ,
    output wire [ 10:0] emac_len_final3     ,
    //output wire [  2:0] emac_pri_final3     ,
    output wire         read_finish3

);
//*******************
//DEFINE LOCAL PARAMETER
//*******************
//parameter(s)

//交叉节点乒乓RAM写入w256-d64
//6'b000000--队列号-帧长-目的端口列表
//6'b000001--SRAM_memory读出的数据
//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
//状态机
// reg          uni_buffer_val0_dl;
// reg          uni_buffer_val1_dl;
// reg          uni_buffer_val2_dl;
// reg          uni_buffer_val3_dl;
// reg          mul_buffer_val0_dl;
// reg          mul_buffer_val1_dl;
// reg          mul_buffer_val2_dl;
// reg          mul_buffer_val3_dl;
//WIRES
//crossbar乒乓ram缓存有效
wire         uni_buffer_val0;
wire         uni_buffer_val1;
wire         uni_buffer_val2;
wire         uni_buffer_val3;
wire         mul_buffer_val0;
wire         mul_buffer_val1;
wire         mul_buffer_val2;
wire         mul_buffer_val3;
//控制各个crossbar双口RAM接收使能
wire         mac_dest_port0_en;
wire         mac_dest_port1_en;
wire         mac_dest_port2_en;
wire         mac_dest_port3_en;
//各个crossbar双口RAM输入数据
wire [255:0] emac_data_in0    ;
wire         emac_data_wren0  ;
wire [  5:0] rx_address_dpram0;
wire         mul_indicate0    ;

wire [255:0] emac_data_in1    ;
wire         emac_data_wren1  ;
wire [  5:0] rx_address_dpram1;
wire         mul_indicate1    ;

wire [255:0] emac_data_in2    ;
wire         emac_data_wren2  ;
wire [  5:0] rx_address_dpram2;
wire         mul_indicate2    ;

wire [255:0] emac_data_in3    ;
wire         emac_data_wren3  ;
wire [  5:0] rx_address_dpram3;
wire         mul_indicate3    ;


//*********************
//MAIN CORE
//********************* 
assign mac_dest_port0_en = mac_dest_port_in[0];
assign mac_dest_port1_en = mac_dest_port_in[1];
assign mac_dest_port2_en = mac_dest_port_in[2];
assign mac_dest_port3_en = mac_dest_port_in[3];

assign emac_data_in0 = mac_dest_port0_en ? emac_data_in : 256'b0;
assign emac_data_in1 = mac_dest_port1_en ? emac_data_in : 256'b0;
assign emac_data_in2 = mac_dest_port2_en ? emac_data_in : 256'b0;
assign emac_data_in3 = mac_dest_port3_en ? emac_data_in : 256'b0;

assign emac_data_wren0 = mac_dest_port0_en ? emac_data_wren : 1'b0;
assign emac_data_wren1 = mac_dest_port1_en ? emac_data_wren : 1'b0;
assign emac_data_wren2 = mac_dest_port2_en ? emac_data_wren : 1'b0;
assign emac_data_wren3 = mac_dest_port3_en ? emac_data_wren : 1'b0;

assign rx_address_dpram0 = mac_dest_port0_en ? rx_address_dpram : 6'b0;
assign rx_address_dpram1 = mac_dest_port1_en ? rx_address_dpram : 6'b0;
assign rx_address_dpram2 = mac_dest_port2_en ? rx_address_dpram : 6'b0;
assign rx_address_dpram3 = mac_dest_port3_en ? rx_address_dpram : 6'b0;

assign mul_indicate0 = mac_dest_port0_en ? mul_indicate : 1'b0;
assign mul_indicate1 = mac_dest_port1_en ? mul_indicate : 1'b0;
assign mul_indicate2 = mac_dest_port2_en ? mul_indicate : 1'b0;
assign mul_indicate3 = mac_dest_port3_en ? mul_indicate : 1'b0;

//*********************
//INSTANTCE MODULE
//*********************
    crossbar_ctl crossbar_ctl_00(
            .clk               (clk),
            .rst_n             (rst_n),
            .ram_2p_cfg_register(ram_2p_cfg_register),
            .emac_data_in      (emac_data_in0),
            .emac_data_wren    (emac_data_wren0),
            .rx_address_dpram  (rx_address_dpram0),
            .mul_indicate      (mul_indicate0),
            .uni_buffer_val    (uni_buffer_val0),
            .mul_buffer_val    (mul_buffer_val0),
            .emac_rx_ready     (emac_rx_ready0),
            .emac_data_final   (emac_data_final0),
            .emac_dval_final   (emac_dval_final0),
            .emac_dsav_final   (emac_dsav_final0),
            .emac_sop_final    (emac_sop_final0),
            .emac_eop_final    (emac_eop_final0),
            .emac_mod_final    (emac_mod_final0),
            .mac_dest_port_out (mac_dest_port_out0),
            .uni_out_busy      (uni_out_busy0),
            .mul_out_busy      (mul_out_busy0),
            .out_enable        (out_enable0),
            .emac_len_final    (emac_len_final0),
            //.emac_pri_final    (emac_pri_final0),
            .read_finish       (read_finish0)
        );

    crossbar_ctl crossbar_ctl_01(
            .clk               (clk),
            .rst_n             (rst_n),
            .ram_2p_cfg_register(ram_2p_cfg_register),
            .emac_data_in      (emac_data_in1),
            .emac_data_wren    (emac_data_wren1),
            .rx_address_dpram  (rx_address_dpram1),
            .mul_indicate      (mul_indicate1),
            .uni_buffer_val    (uni_buffer_val1),
            .mul_buffer_val    (mul_buffer_val1),
            .emac_rx_ready     (emac_rx_ready1),
            .emac_data_final   (emac_data_final1),
            .emac_dval_final   (emac_dval_final1),
            .emac_dsav_final   (emac_dsav_final1),
            .emac_sop_final    (emac_sop_final1),
            .emac_eop_final    (emac_eop_final1),
            .emac_mod_final    (emac_mod_final1),
            .mac_dest_port_out (mac_dest_port_out1),
            .uni_out_busy      (uni_out_busy1),
            .mul_out_busy      (mul_out_busy1),
            .out_enable        (out_enable1),
            .emac_len_final    (emac_len_final1),
            //.emac_pri_final    (emac_pri_final1),
            .read_finish       (read_finish1)
        );

    crossbar_ctl_2 crossbar_ctl_10_11(
            .clk                (clk),
            .rst_n              (rst_n),
            .ram_2p_cfg_register(ram_2p_cfg_register),
            .emac_data_in0      (emac_data_in2),
            .emac_data_wren0    (emac_data_wren2),
            .rx_address_dpram0  (rx_address_dpram2),
            .mul_indicate0      (mul_indicate2),
            .uni_buffer_val0    (uni_buffer_val2),
            .mul_buffer_val0    (mul_buffer_val2),
            .emac_rx_ready0     (emac_rx_ready2),
            .emac_data_final0   (emac_data_final2),
            .emac_dval_final0   (emac_dval_final2),
            .emac_dsav_final0   (emac_dsav_final2),
            .emac_sop_final0    (emac_sop_final2),
            .emac_eop_final0    (emac_eop_final2),
            .emac_mod_final0    (emac_mod_final2),
            .mac_dest_port_out0 (mac_dest_port_out2),
            .uni_out_busy0      (uni_out_busy2),
            .mul_out_busy0      (mul_out_busy2),
            .out_enable0        (out_enable2),
            .emac_len_final0    (emac_len_final2),
            //.emac_pri_final0    (emac_pri_final2),
            .read_finish0       (read_finish2),
            .emac_data_in1      (emac_data_in3),
            .emac_data_wren1    (emac_data_wren3),
            .rx_address_dpram1  (rx_address_dpram3),
            .mul_indicate1      (mul_indicate3),
            .uni_buffer_val1    (uni_buffer_val3),
            .mul_buffer_val1    (mul_buffer_val3),
            .emac_rx_ready1     (emac_rx_ready3),
            .emac_data_final1   (emac_data_final3),
            .emac_dval_final1   (emac_dval_final3),
            .emac_dsav_final1   (emac_dsav_final3),
            .emac_sop_final1    (emac_sop_final3),
            .emac_eop_final1    (emac_eop_final3),
            .emac_mod_final1    (emac_mod_final3),
            .mac_dest_port_out1 (mac_dest_port_out3),
            .uni_out_busy1      (uni_out_busy3),
            .mul_out_busy1      (mul_out_busy3),
            .out_enable1        (out_enable3),
            .emac_len_final1    (emac_len_final3),
            //.emac_pri_final1    (emac_pri_final3),
            .read_finish1       (read_finish3)
        );

// always @(posedge clk or negedge rst_n) begin
//     if (!rst_n) begin
//         // reset
//         uni_buffer_val0_dl     <= 1'b0;
//         uni_buffer_val1_dl     <= 1'b0;
//         uni_buffer_val2_dl     <= 1'b0;
//         uni_buffer_val3_dl     <= 1'b0;
//         mul_buffer_val0_dl     <= 1'b0;
//         mul_buffer_val1_dl     <= 1'b0;
//         mul_buffer_val2_dl     <= 1'b0;
//         mul_buffer_val3_dl     <= 1'b0;
//     end
//     else begin
//         uni_buffer_val0_dl     <= uni_buffer_val0;
//         uni_buffer_val1_dl     <= uni_buffer_val1;
//         uni_buffer_val2_dl     <= uni_buffer_val2;
//         uni_buffer_val3_dl     <= uni_buffer_val3;
//         mul_buffer_val0_dl     <= mul_buffer_val0;
//         mul_buffer_val1_dl     <= mul_buffer_val1;
//         mul_buffer_val2_dl     <= mul_buffer_val2;
//         mul_buffer_val3_dl     <= mul_buffer_val3;
//     end
// end


assign  uni_tx_rdy0 = (/* uni_buffer_val0_dl ||  */uni_buffer_val0);
assign  uni_tx_rdy1 = (/* uni_buffer_val1_dl ||  */uni_buffer_val1);
assign  uni_tx_rdy2 = (/* uni_buffer_val2_dl ||  */uni_buffer_val2);
assign  uni_tx_rdy3 = (/* uni_buffer_val3_dl ||  */uni_buffer_val3);
assign  mul_tx_rdy0 = (/* mul_buffer_val0_dl ||  */mul_buffer_val0);
assign  mul_tx_rdy1 = (/* mul_buffer_val1_dl ||  */mul_buffer_val1);
assign  mul_tx_rdy2 = (/* mul_buffer_val2_dl ||  */mul_buffer_val2);
assign  mul_tx_rdy3 = (/* mul_buffer_val3_dl ||  */mul_buffer_val3);


endmodule
